/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.aseclipse.core.runtime.registry.classes {

import org.aseclipse.core.runtime.registry.IExtension;
import org.aseclipse.core.runtime.registry.IExtensionPoint;
import org.aseclipse.osgi.Bundle;
import org.aseclipse.osgi.classes.BundleFrameworkImpl;

import mx.collections.ArrayCollection;

/**
 * An object which represents the user-defined contents of a bundle model
 * in a extensions manifest.
 */
public class BundleModel extends RegistryModelObject implements IRegistryElement {
    
	private static const DEFAULT_BUNDLE_NAME:String = "plugin"; //$NON-NLS-1$
	private static const KEY_PREFIX:String = "%"; //$NON-NLS-1$
	private static const KEY_DOUBLE_PREFIX:String = "%%"; //$NON-NLS-1$	

	private var hostId:String;
	private var fragments:Array; // BundleModel[] 
	private var activator:String;
	private var libraries:Array = new Array(); // String[]
	private var locales:Array = new Array(); // String[]
	private var styles:Array = new Array(); // String[]
	private var dependedPlugins:Array = new Array(); // String[]
	
	private var extensionPoints:Array = new Array(); // IExtensionPoint[] 
	private var extensions:Array = new Array(); // IExtension[] 

	private var bundleId:int; //Introduced to fix #46308 

	private var schemaVersion:String;
    private var pluginVersion:String;
    private var pluginId:String;
    
    // reference to bundle framework for ConfigurationElement
    public var framework:BundleFrameworkImpl;
    public var owner:Bundle;
    /******
    * Memory management strategy
    * 
    */ 
	public function getPluginActivator():String {
	    return activator;
	}
	
	public function setPluginActivator(claz:String):void {
	    activator = claz;
	}
	
	public function getLibraries():Array {
	    return libraries;
	}
	
	public function setLibraries(libs:Array):void {
	    libraries = libs;
	}
		
	public function getStyles():Array {
	    return styles;
	}
	public function setStyles(libs:Array):void {
	    styles = libs;
	}
	public function getLocales():Array {
	    return locales;
	}
	public function setLocales(libs:Array):void {
	    locales = libs;
	}
	public function getVersion():String {
	    return pluginVersion;
	}
	
	public function setVersion(ver:String):void {
	    pluginVersion = ver;
	}
	
	public function addLibrary(lib:Object):void {
	    var array:Array = getLibraries();
	    if(array == null) {
	        array = new Array();
	        setLibraries(array);
	    }
	    array.push(lib);
	}
	
	public function addStyle(lib:Object):void {
	    var array:Array = getStyles();
	    if(array == null) {
	        array = new Array();
	        setStyles(array);
	    }
	    array.push(lib);
	}
	
	public function addLocale(lib:Object):void {
	    var array:Array = getLocales();
	    if(array == null) {
	        array = new Array();
	        setLocales(array);
	    }
	    array.push(lib);
	}
	
	public function getRequirePlugins():Array {
	    return dependedPlugins;
	}
	
	public function setRequirePlugins(plugins:Array):void {
	    dependedPlugins = plugins;
	}
	
	public function addRequirePlugin(plugin:String):void {
	    var array:Array = getRequirePlugins();
	    if(array == null) {
	        array = new Array();
	        setRequirePlugins(array);
	    }
	    array.push(plugin);
	}
	
	public function getUniqueIdentifier():String {
		return getName();
	}
	public function setUniqueIdentifier(value:String):void {
		setName(value);
	}
	public function setExtensions(value:Array):void {
		assertIsWriteable();
		extensions = value;
	}
	public function getExtension(id:String):IExtension {
		if (id == null)
			return null;
		var list:Array = getExtensions();
		if (list == null)
			return null;
		for (var i:int = 0; i < list.length; i++) {
			if (id == (list[i] as IExtension).getUniqueIdentifier())
				return list[i] as IExtension;
		}
		return null;
	}
	
	public function getExtensions():Array {
		return extensions;
	}
	
	public function addExtension(ext:Extension):void {
	    getExtensions().push(ext);
	}
	
	override public function markReadOnly():void {
		super.markReadOnly();
		if (extensionPoints != null)
			for (var i:int = 0; i < extensionPoints.length; i++)
				 (extensionPoints[i] as ExtensionPoint).markReadOnly();
		if (extensions != null)
			for (var j:int = 0; j < extensions.length; j++)
				 (extensions[j] as Extension).markReadOnly();
	}
	
	public function setExtensionPoints(value:Array):void { // IExtensionPoint[]
		assertIsWriteable();
		extensionPoints = value;
	}
	public function getExtensionPoint(xpt:String):IExtensionPoint {
		if (xpt == null)
			return null;
		var list:Array = getExtensionPoints();
		if (list == null)
			return null;
		for (var i:int = 0; i < list.length; i++) {
			if (xpt == (list[i] as IExtensionPoint).getSimpleIdentifier())
				return (list[i] as IExtensionPoint);
		}
		return null;
	}
	
	public function getExtensionPoints():Array {
		return extensionPoints;
	}
	
	public function addExtensionPoint(extPoint:ExtensionPoint):void {
	    getExtensionPoints().push(extPoint);
	}
	
	public function setHostIdentifier(value:String):void {
		hostId = value;
	}
	public function getHostIdentifier():String {
		return hostId;
	}
	public function isFragment():Boolean {
		return hostId != null;
	}
	public function addFragment(fragment:BundleModel):void {
		if (fragments == null) {
			fragments = new Array(); // { fragment };
		}
		fragments.push(fragment);
	}
	public function removeFragment(fragment:BundleModel):void {
		if (fragments == null)
			return;
		var array:ArrayCollection = new ArrayCollection(fragments);
		for (var i:int = 0; i < array.length; i++) {
		    var item:BundleModel = array.getItemAt(i) as BundleModel;
		    if(item.getId() == fragment.getId()) {
		        array.removeItemAt(i);
		        break;
		    }
		}
	}
	override public function toString():String {
		return "BundleModel: " + getName();
	}

	public function getFragments():Array {
		return fragments;
	}

	public function setFragments(value:Array):void {
		fragments = value;
	}

	protected function setSchemaVersion(schemaVersion:String):void {
		this.schemaVersion = schemaVersion;
	}

	public function getId():int {
		return bundleId;
	}
	public function setId(value:int):void {
		bundleId = value;
	}
	
	public function destroy():void {
	    fragments = null;
	    new ArrayCollection(libraries).removeAll();
	    new ArrayCollection(locales).removeAll();
	    new ArrayCollection(styles).removeAll();
	    new ArrayCollection(dependedPlugins).removeAll();
	    new ArrayCollection(extensionPoints).removeAll();
	    new ArrayCollection(extensions).removeAll();
	} 
}}
